package org.hyn.gateway.socket.handlers;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.JSON;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.*;
import org.hyn.gateway.bind.IGenericReference;
import org.hyn.gateway.mapping.HttpStatement;
import org.hyn.gateway.session.Configuration;
import org.hyn.gateway.session.GatewaySession;
import org.hyn.gateway.session.defaults.DefaultGatewaySessionFactory;
import org.hyn.gateway.socket.BaseHandler;
import org.hyn.gateway.socket.agreement.AgreementConstants;
import org.hyn.gateway.socket.agreement.GatewayResultMessage;
import org.hyn.gateway.socket.agreement.RequestParser;
import org.hyn.gateway.socket.agreement.ResponseParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

/**
 * @author franyhu
 * @description 会话服务处理器
 * @date 2025/2/8
 */
public class GatewayServerHandler extends BaseHandler<FullHttpRequest> {

    private final Logger logger = LoggerFactory.getLogger(GatewayServerHandler.class);

    private final Configuration configuration;

    public GatewayServerHandler(Configuration configuration) {
        this.configuration = configuration;
    }

    @Override
    protected void session(ChannelHandlerContext ctx, Channel channel, FullHttpRequest request) {
        logger.info("网关接受请求【全局】 uri:{} method:{}", request.uri(), request.method());

        try {
            // 1.解析请求参数
            RequestParser requestParser = new RequestParser(request);
            String uri = requestParser.getUri();

            // 2.保存信息 HttpStatement、Header=token
            // set(httpStatement)：将httpStatement对象作为值存储到通道的属性中。这个值可以在通道的生命周期内通过同样的AttributeKey获取。
            HttpStatement httpStatement = configuration.getHttpStatement(uri);
            channel.attr(AgreementConstants.HTTP_STATEMENT).set(httpStatement);

            // 3.放行服务
            // 增加请求对象的引用计数。这是因为Netty使用引用计数来管理对象的生命周期，通过retain()方法确保对象不会被过早释放。
            request.retain();
            // 将请求传递给下一个处理器。这意味着当前处理器已经完成了自己的工作，现在将请求交给下一个处理器继续处理。
            // 这种方式实现了Netty的管道（Pipeline）机制，允许请求在多个处理器之间流动。
            ctx.fireChannelRead(request);
        } catch (Exception e) {
            // 4.封装返回结果
            DefaultFullHttpResponse response = new ResponseParser().parse(
                    GatewayResultMessage.buildError(AgreementConstants.ResponseCode._500.getCode(), "网关协议调用失败 " + e.getMessage())
            );
            channel.writeAndFlush(response);
        }
    }
}
